package com.yz.base;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.cglib.core.Converter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
public class FastCopyUtils {

    public static Map<String, BeanCopier> CACHE_MAP = new HashMap<>();

    public static void addBothWayBeanCopy(Class<?> clz1, Class<?> clz2) {
        addBothWayBeanCopy(clz1, clz2, false);
    }

    public static void addBothWayBeanCopy(Class<?> clz1, Class<?> clz2, boolean useConverter) {
        CACHE_MAP.put(buildCacheKey(clz1, clz2), BeanCopier.create(clz1, clz2, useConverter));
        CACHE_MAP.put(buildCacheKey(clz2, clz1), BeanCopier.create(clz2, clz1, useConverter));
    }

    public static <T> T copy(Object form, Class<T> to) {
        T targetSource = null;
        try {
            targetSource = to.newInstance();
        } catch (Exception e) {
            log.error("创建对象发生异常: ", e);
        }
        return copy(form, to, targetSource, null);
    }

    public static <T> T copy(Object form, T to) {
        return copy(form, to.getClass(), to, null);
    }

    public static <F, T> List<T> listCopy(List<F> formList, Class<T> to) {
        List<T> toList = new ArrayList<>(formList.size());
        formList.forEach(v -> {
            toList.add(copy(v, to));
        });
        return toList;
    }

    public static Object copy(Object form, Class<?> to, Object targetSource) {
        return copy(form, to, targetSource, null);
    }

    public static <T> T copy(Object form, Class<?> to, T targetSource, Converter converter) {
        if (form == null) {
            return targetSource;
        }
        final Class<?> formClass = form.getClass();
        String cacheKey = buildCacheKey(formClass, to);
        if (!CACHE_MAP.containsKey(cacheKey)) {
            addBothWayBeanCopy(formClass, to);
        }
        CACHE_MAP.get(cacheKey).copy(form, targetSource, converter);
        return targetSource;
    }

    public static String buildCacheKey(Class<?> clz1, Class<?> clz2) {
        return clz1.getSimpleName() + "_" + clz2.getSimpleName();
    }

    private static Converter customerConverter() {
        return null;
    }


}
